#include "Queue.h"

// 队列的初始化

void QueueInit (Queue* pq)
{

    assert (pq) ;

    pq -> phead = pq -> ptail = NULL ;

    // pq -> size = 0 ; // 初始数据为0

}

// 队列的销毁

void QueueDestory (Queue* pq)
{

    assert (pq) ;

    QueueNode* pcur = pq -> phead ;

    while (pcur) // 一直销毁直到为空
    {

        QueueNode* next = pcur -> next ;

        free (pcur) ;

        pcur = next ;

    }

    pq -> phead = pq -> ptail = NULL ;

    // pq -> size = 0 // 重置有效元素个数

}

// 入队---队尾

void QueuePush (Queue* pq , QDataType x)
{

    assert (pq) ;

    QueueNode* newnode = (QueueNode*) malloc (sizeof (QueueNode)) ;

    if (newnode == NULL)
    {

        perror ("malloc fail!") ;

        exit (1) ;

    }

    newnode -> data = x ;

    newnode -> next = NULL ;

    // 队列为空

    if (pq -> phead == NULL)
    {

        pq -> phead = pq -> ptail = newnode ;

    }

    else
    {

        // 队列非空

        pq -> ptail -> next = newnode ;

        pq -> ptail = pq -> ptail -> next ;

    }

    // pq -> size++ ; // 有效数据加1

}

// 出队---队头

void QueuePop (Queue* pq)
{

    assert (!QueueEmpty (pq)) ;

    // 只有一个节点,phead和ptail都置为空

    if (pq -> phead == pq -> ptail)
    {

        free (pq -> phead) ;

        pq -> phead = pq -> ptail = NULL ;

    }

    else
    {

        QueueNode* next = pq -> phead -> next ;

        free (pq -> phead) ;

        pq -> phead = next ;

    }

    // pq -> size-- // 有效数据减1

}

// 队列判空

bool QueueEmpty (Queue* pq)
{

    assert (pq) ;

    return pq -> phead == NULL ;

}

// 取队头数据

QDataType QueueFront (Queue* pq)
{

    assert (!QueueEmpty (pq)) ; // 队列不为空才能取数据

    return pq -> phead -> data ;

}

// 取队尾数据

QDataType QueueBack (Queue* pq)
{

    assert (!QueueEmpty (pq)) ;

    return pq -> ptail -> data ;

}


// 取队列有效元素个数

int QueueSize (Queue* pq)
{

    assert (pq) ;

    // 第一种方式: 遍历链表---适用于不会频繁调用队列有效个数的场景

    QueueNode* pcur = pq -> phead ;

    int size = 0 ;

    while (pcur)
    {

        size++ ;

        pcur = pcur -> next ;

    }

    return size ;

    // 第二种方式: 在结构体设置size变量,在调用的时候自增减---适用于需要频繁调用队列有效个数的场景

    // return size ;
    
}